import os
import random
import numpy as np

import pandas as pd
import tomli
import torch

from data_parsers import parser_fajsp, parser_fjsp, parser_fjsp_sdst, parser_jsp_fsp
from scheduling_environment.jobShop import JobShop


def load_parameters(config_toml):
    """Load parameters from a toml file"""
    with open(config_toml, "rb") as f:
        config_params = tomli.load(f)
    return config_params


def load_job_shop_env(problem_instance: str, from_absolute_path=False) -> JobShop:
    """
    根据问题实例加载作业车间调度环境。

    本函数通过解析问题实例字符串，创建并返回一个对应的JobShop环境对象。
    不同类型的问题实例（如jsp, fsp, fjsp等）需要调用不同的解析函数。

    参数:
    - problem_instance: 一个字符串，表示问题实例的路径或名称。
    - from_absolute_path: 一个布尔值，表示problem_instance是否是一个绝对路径。

    返回:
    - 一个JobShop环境对象，根据problem_instance参数初始化。
    """
    # 初始化一个JobShop环境对象
    jobShopEnv = JobShop()

    # 根据问题实例类型，调用相应的解析函数
    if '/fsp/' in problem_instance or '/jsp/' in problem_instance:
        jobShopEnv = parser_jsp_fsp.parse_jsp_fsp(jobShopEnv, problem_instance, from_absolute_path)
    elif '/fjsp/' in problem_instance:
        jobShopEnv = parser_fjsp.parse_fjsp(jobShopEnv, problem_instance, from_absolute_path)
    elif '/fjsp_sdst/' in problem_instance:
        jobShopEnv = parser_fjsp_sdst.parse_fjsp_sdst(jobShopEnv, problem_instance, from_absolute_path)
    elif '/fajsp/' in problem_instance:
        jobShopEnv = parser_fajsp.parse_fajsp(jobShopEnv, problem_instance, from_absolute_path)
    else:
        # 如果问题实例类型未识别，抛出异常
        raise NotImplementedError(
            f"""Problem instance {
            problem_instance
            } not implemented"""
        )

    # 设置环境对象的名称为问题实例的标识
    jobShopEnv._name = problem_instance

    # 返回初始化后的JobShop环境对象
    return jobShopEnv



def set_seeds(seed_value=0):
    random.seed(seed_value)
    np.random.seed(seed_value)
    torch.manual_seed(seed_value)
    if torch.cuda.is_available():
        torch.cuda.manual_seed_all(seed_value)


def initialize_device(parameters: dict, method: str = "FJSP_DRL") -> torch.device:
    device_str = "cpu"
    if method == "FJSP_DRL":
        if parameters['test_parameters']['device'] == "cuda":
            device_str = "cuda:0" if torch.cuda.is_available() else "cpu"
    elif method == "DANIEL":
        if parameters["device"]["name"] == "cuda":
            device_str = (
                f"cuda:{parameters['device']['id']}" if torch.cuda.is_available() else "cpu"
            )
    return torch.device(device_str)